using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using server.Hubs;
using server.Models;

namespace server.Controllers
{
	[Route("api/[controller]")]
	[ApiController]
	public class QuestionController : ControllerBase
	{
		private readonly IHubContext<QuestionHub> _hubContext;
	    public QuestionController(IHubContext<QuestionHub> hubContext)
        {
			_hubContext = hubContext;

		}

		private static ConcurrentBag<Question> questions = new ConcurrentBag<Question>{
				new Question {
					Id = Guid.NewGuid(),
					Title = "Welcome",
					Body = "Welcome to the _mini Stack Overflow_ rip-off!\nThis will help showcasing **SignalR** and its integration with **Vue**",
					Answers = new List<Answer> {
						new Answer {
							Body = "Sample answer"
						}
					}
				}
			};

		[HttpGet()]
		public IEnumerable GetQuestions()
		{
			return questions.Select(q => new
			{
				Id = q.Id,
				Title = q.Title,
				Body = q.Body,
				Score = q.Score,
				AnswerCount = q.Answers.Count
			});
		}

		[HttpGet("{id}")]
		public ActionResult GetQuestion(Guid id)
		{
			var question = questions.SingleOrDefault(t => t.Id == id);
			if (question == null)
			{
				return NotFound();
			}

			return new JsonResult(question);
		}

		[HttpPost()]
		public Question AddQuestion([FromBody]Question question)
		{
			question.Id = Guid.NewGuid();
			question.Answers = new List<Answer>();
			questions.Add(question);
			return question;
		}

		[HttpPost("{id}/answer")]
		public ActionResult AddAnswerAsync(Guid id, [FromBody]Answer answer)
		{
			var question = questions.SingleOrDefault(t => t.Id == id);
			if (question == null)
			{
				return NotFound();
			}

			answer.Id = Guid.NewGuid();
			answer.QuestionId = id;
			question.Answers.Add(answer);

			return new JsonResult(answer);
		}

		[HttpPatch("{id}/upvote")]
		public ActionResult UpvoteQuestionAsync(Guid id, [FromQuery]string connectionId)
		{
			var question = questions.SingleOrDefault(t => t.Id == id);
			if (question == null)
			{
				return NotFound();
			}

			// TODO should be interlocked instead
			question.Score++;

			HandleEventAsync(connectionId).Wait();

			return new JsonResult(question);
		}

		[HttpPatch("{id}/downvote")]
		public ActionResult DownvoteQuestionAsync(Guid id)
		{
			var question = questions.SingleOrDefault(t => t.Id == id);
			if (question == null)
			{
				return NotFound();
			}

			// TODO should be interlocked instead
			question.Score--;
			return new JsonResult(question);
		}

		private async Task HandleEventAsync(string connectionId)
		{
			Console.WriteLine("server send message by singnalr!");

			var eventName = "message.created";
			var message = $"hello world,{connectionId}";	

			await _hubContext.Clients
				.Client(connectionId)
				.SendAsync("ReceiveMessage", new { @event = eventName, data = message });
		}
	}
}